package com.gopay.bis.service.bank.impl;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import com.gopay.bis.manager.bank.BankOrderManager;
import com.gopay.bis.service.bank.BankOrderService;
import com.gopay.common.constants.bank.BankOrderStatus;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.cps.dao.bank.BankOrderQueryDAO;
import com.gopay.common.domain.bank.BankOrder;
import com.gopay.common.domain.bank.BankOrderDealLog;
import com.gopay.common.domain.bank.BankOrderExt;
import com.gopay.common.domain.bank.BankRouteLog;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.BcdlMessage;
import com.gopay.common.domain.bank.BcdlQueryBalance;
import com.gopay.common.domain.bank.BcdlSendBankLog;
import com.gopay.common.domain.bank.SendBankOrderCust;
import com.gopay.common.domain.bis.BisBankBcdlOrder;
import com.gopay.common.domain.bis.RouteMessage;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.DateUtils;
import com.gopay.common.util.TransUtil;

/**
 * 银行流水Service实现
 * 
 * @BankOrderServiceImpl.java
 * @author yaobo
 * @2013-2-5 下午04:02:05 www.gopay.com.cn Inc.All rights reserved.
 */
public class BankOrderServiceImpl implements BankOrderService {

    @Resource(name = "bankOrderManager")
    private BankOrderManager bankOrderManager;
    
    @Resource(name = "bankOrderQueryDAO")
   private BankOrderQueryDAO bankOrderQueryDAO;
    

    /**
     * 
     */
    public BankOrder addBankOrder(BaseMessage base) throws GopayException {
        
    	String outOrderId = null;
    	/*//设置银企直连订单号
        if (BisBankBusinessProd._09.equals(base.getBankBusProd())){
        	outOrderId = bankOrderQueryDAO.getNextId("ORDER_ID_SEQ");
        	outOrderId = StringUtils.leftPad(outOrderId, 8, "0");
        	outOrderId = DateUtils.now2string("yyyyMMdd") + outOrderId;
        }
        //设置网关支付订单号
        else{
        	outOrderId = base.getBankOrderId();
        }*/
    	outOrderId = base.getBankOrderId();
        // 检查银企直连订单号是否重复
        if (!BisBankBusinessProd._09.equals(base.getBankBusProd())
        		&& bankOrderManager.getBankOrderById(outOrderId) != null) {
            throw new GopayException("100E5013", "bia_bank_order exits! gopayOutOrderId=" + outOrderId);
        }

        Date curDate = DateUtils.getSystemDate();
        BankOrder bankOrder = new BankOrder();
        bankOrder.setBankBizProdCode(base.getBankBusProd().value);
        bankOrder.setBankCode(base.getBank());
        bankOrder.setBankOrderId(base.getBankReturnOrderId());
        bankOrder.setBankRespCode("");
        bankOrder.setCreatedTs(curDate);
        bankOrder.setInterfaceChennelCode(base.getBankIntrChann().value);
        bankOrder.setLastCheckBillTime(null);
        bankOrder.setLastUpdTrancode("");
        bankOrder.setLastUpdTs(curDate);
        bankOrder.setLock(0);
        bankOrder.setOrderType(base.getBankOrderType());//订单类型
        bankOrder.setOrderId(base.getOrderId());
        bankOrder.setOrderStatus(BankOrderStatus.PROCESS);
        bankOrder.setRemark2("");
        bankOrder.setRemark3("");
        bankOrder.setSendBankTm(curDate);
        bankOrder.setTotalCheckTimes(0);
        bankOrder.setTranFinishTime(null);
        if(BisBankBusinessProd._09.equals(base.getBankBusProd())){
       	 bankOrder.setOrderStatus(BankOrderStatus.ACCEPTED);
       	 bankOrder.setRemark2(base.getNotifyUrl());
       }else if(BisBankBusinessProd._12.equals(base.getBankBusProd())){
       	 bankOrder.setOrderStatus(BankOrderStatus.ACCEPTED);
       }else {
       	 bankOrder.setOrderStatus(BankOrderStatus.PROCESS);
       }
        bankOrder.setLastUpdTs(curDate);
        //是否禁用信用卡
        if(!base.isSupportCredit()){
        	bankOrder.setDisableCreditCard("1");
        }
        // 是否为小额风险商户
        if(base.isSmallMer()){
            bankOrder.setDisableSmallMerchant("1");
        }
        // 是否为特殊大额商户
        if(base.isBigMer()){
            bankOrder.setSpecialBigMerchant("1");
        }
        if(BisBankBusinessProd._09.equals(base.getBankBusProd())){
        	// save银企直连订单
        	BisBankBcdlOrder bcdl = new BisBankBcdlOrder();
        	BcdlMessage bcdlMsg = (BcdlMessage)base;
        	bcdl.setGopayOutOrderId(outOrderId);
        	bcdl.setRecvPbocBankCode(bcdlMsg.getRecvBankCode());// 央行代码
        	bcdl.setRecvBankName(bcdlMsg.getRecvBankName());// 央行名称
        	bcdl.setRecvBankPbocNum(bcdlMsg.getPbocBankBranchCode());// 联行号
        	bcdl.setRecvBankBranchName(bcdlMsg.getPbocBankBranchName());// 联行名
        	bcdl.setRecvBankAcctNum(bcdlMsg.getRecvBankAcctNum());// 账号
        	bcdl.setRecvBankAcctName(bcdlMsg.getRecvBankAcctName());// 户名
        	bcdl.setRecvBankProvinceCode(bcdlMsg.getRecvBankProvNo());// 省代码
        	bcdl.setRecvBankProvinceName(bcdlMsg.getRecvBankProvName());// 省名称
        	bcdl.setRecvBankCityCode(bcdlMsg.getRecvBankCityCode());// 城市代码
        	bcdl.setRecvBankCityName(bcdlMsg.getRecvBankCityName());// 城市名称
        	
        	bcdl.setBcFlag(bcdlMsg.getDcblType());
        	bcdl.setCrossBank(bcdlMsg.getSysIOFlg());
        	bcdl.setUrgent(bcdlMsg.getEmergency());
        	//是否重发 1 是 0 否
        	bcdl.setReonlinepay(0);
        	
        	bankOrderManager.addBankBcdlOrder(bcdl);
        }
        /**
         * 三方支付APP保存APPID
         */
        if(BisBankBusinessProd._17.equals(base.getBankBusProd())){
       	 bankOrder.setAppId(base.getAppId());
       }
		if (BisBankBusinessProd._16.equals(base.getBankBusProd())
				|| BisBankBusinessProd._18.equals(base.getBankBusProd())
				|| BisBankBusinessProd._25.equals(base.getBankBusProd())
				){
        	if(base.isMerchantModel){
        		BankOrderExt bankOrderExt=new BankOrderExt();
        		bankOrderExt.setOutOrderId(outOrderId);
        		bankOrderExt.setOrderId(base.getOrderId());
        		bankOrderExt.setCreatedTs(curDate);
        		bankOrderExt.setLastUpdTs(curDate);
        		bankOrderExt.setMerchantId(base.getMerID());
        		bankOrderExt.setMerchantKey(base.getPrivateKeyPath());
        		bankOrderManager.addBankOrderExt(bankOrderExt);
        	}
          }
        bankOrder.setOutOrderId(outOrderId);
        if(BisBankBusinessProd._26.equals(base.getBankBusProd())){
            bankOrder.setOriOutOrderId(base.getCzOriBankOrderId()); // 冲正交易增加原银行订单号
        }else{
            bankOrder.setOriOutOrderId(base.getTkOriBankOrderId()); // 退款交易增加原银行订单号
        }
        
        bankOrder.setSendBankAmt(base.getAmount());
        //新增交易批次号
        bankOrder.setTransBatchNo(base.getTransBatchNo());
        bankOrder = bankOrderManager.addBankOrder(bankOrder);
        return bankOrder;
    }

  
    public SendBankOrderCust addSendBankOrder(BaseMessage base) {
    	SendBankOrderCust orderCust = new SendBankOrderCust();
    	orderCust.setOrderId(base.getOrderId());
    	orderCust.setOutOrderId(base.getBankOrderId());
    	orderCust.setSendBankCustId(base.getSendBankCustId());
    	orderCust = bankOrderManager.addSendBankOrder(orderCust);
        
        return orderCust;
    }
    
    @Override
    public void updateBankOrder(BankOrder bankOrder) {
        bankOrderManager.updateBankOrder(bankOrder);
    }

    @Override
    public BankOrder getBankOrderById(String outOrderId) {
        BankOrder bankOrder = bankOrderManager.getBankOrderById(outOrderId);

        return bankOrder;
    }

    @Override
    public int updateBackSuccess(String outOrderId) {
        int result = bankOrderManager.updateBackSuccess(outOrderId);

        return result;
    }
    
    /**
     * 获取银行流水
     * 
     * @param orderId
     * @return
     */
    public List<BankOrder> getBankOrdersByGopayOrderId(String orderId){
    	List<BankOrder> bankOrders = bankOrderManager.getBankOrdersByGopayOrderId(orderId);
        return bankOrders;
    }

	@Override
	public int updateBpsSuccess(String orderId) {
		int result = bankOrderManager.updateBpsSuccess(orderId);
		return result;
	}

	@Override
	public int updateBpsFail(String orderId) {
		int result = bankOrderManager.updateBpsFail(orderId);
		return result;
	}

	@Override
	public int updateBpsOther(String orderId) {
		int result = bankOrderManager.updateBpsOther(orderId);
		return result;
	}

    @Override
    public int updateInAcctFail(String orderId) {
        int result = bankOrderManager.updateInAcctFail(orderId);
        return result;
    }

    @Override
    public List<BcdlQueryBalance> getBcdlQueryByBankCodeAndOrderStatus(String bankCode, String queryOrderStatus) {
        return bankOrderManager.getBcdlQueryByBankCodeAndOrderStatus(bankCode, queryOrderStatus);
    }

    @Override
    public BcdlQueryBalance addBcdlQueryOrder(BaseMessage base) throws GopayException {
        String queryOrderId = "";
        queryOrderId = bankOrderQueryDAO.getNextId("ORDER_ID_SEQ");
        queryOrderId = StringUtils.leftPad(queryOrderId, 8, "0");
        queryOrderId = DateUtils.now2string("yyyyMMdd") + queryOrderId;
        queryOrderId = "QU" + TransUtil.processOrderIdTo14Digit(queryOrderId);
        base.setOrderId(queryOrderId);
        
        // 检查查询余额订单号是否重复
        if (bankOrderManager.getBcdlQueryById(queryOrderId) != null) {
            throw new GopayException("100E5013", "bis_bcdl_query_balance exits! queryOrderId=" + queryOrderId);
        }
        Date curDate = DateUtils.getSystemDate();
        BcdlQueryBalance queryOrder = new BcdlQueryBalance();
        queryOrder.setQueryOrderId(queryOrderId);
        queryOrder.setQueryBankCode(base.getBank());
        queryOrder.setQueryCreatTime(curDate);
        queryOrder.setQueryOrderStatus(BankOrderStatus.ACCEPTED);
        queryOrder.setQueryLastTime(curDate);
        queryOrder = bankOrderManager.addBcdlQueryOrder(queryOrder);
        return queryOrder;
    }

    @Override
    public void updateBcdlQueryOrder(BcdlQueryBalance bcdlQuery) {
        bankOrderManager.updateBcdlQueryOrder(bcdlQuery);
    }

    @Override
    public BcdlQueryBalance getBcdlQueryById(String orderId) {
        return bankOrderManager.getBcdlQueryById(orderId);
    }
    
	@Override
	public void addBankOrderDealLog(BankOrder bankOrder) {
		BankOrderDealLog bankOrderDealLog = new BankOrderDealLog();
		bankOrderDealLog.setGopayOrderId(bankOrder.getOrderId());
		bankOrderDealLog.setBeforeShapshot(ToStringBuilder.reflectionToString(bankOrder,
				ToStringStyle.DEFAULT_STYLE));
		bankOrderDealLog.setCreatedTs(new Date());
		bankOrderDealLog.setLastUpdTs(new Date());
		bankOrderManager.addBankOrderDealLog(bankOrderDealLog);
	}


    @Override
    public List<BankOrder> getBankOrdersByOriBankOrderId(String bankOrderId) {
        List<BankOrder> bankOrders = bankOrderManager.getBankOrdersByOriBankOrderId(bankOrderId);
        return bankOrders;
    }


    @Override
    public void addBankRouteLog(RouteMessage routeMessage) {
        BankRouteLog bankRouteLog = new BankRouteLog();
        bankRouteLog.setGopayOrderId(routeMessage.getGopayOrderId());
        bankRouteLog.setBankCode(routeMessage.getBankCode());
        bankRouteLog.setProdCode(routeMessage.getProdCode());
        bankRouteLog.setSolutionId(routeMessage.getSolutionId());
        bankRouteLog.setRuleId(routeMessage.getRuleId());
        bankRouteLog.setChannelCode(routeMessage.getChanellCode());
        bankRouteLog.setStartEp(routeMessage.getStartExp());
        bankRouteLog.setEndEp(routeMessage.getEndExp());
        bankRouteLog.setSolutionName(routeMessage.getSolutionName());
        bankRouteLog.setRuleName(routeMessage.getRuleName());
        bankRouteLog.setRemark(routeMessage.getSpecial());
        // 增加路由交易金额
        bankRouteLog.setTransAmt(routeMessage.getTransAmt());
        bankOrderManager.addBankRouteLog(bankRouteLog);
    }


    @Override
    public void updateBankBcdlOrder(BisBankBcdlOrder bcdlOrder) {
        bankOrderManager.updateBankBcdlOrder(bcdlOrder);
    }


    @Override
    public BisBankBcdlOrder getBankBcdlOrderById(String orderId) {
        return bankOrderManager.getBankBcdlOrderById(orderId);
    }


	@Override
	public BcdlSendBankLog getBcdlSendLogById(String orderId) {
		return bankOrderManager.getBcdlSendLogById(orderId);
	}


	@Override
	public void deleteBcdlSendLog(BcdlSendBankLog bcdlSendBankLog) {
		bankOrderManager.deleteBcdlSendLog(bcdlSendBankLog);
	}

}
